package com.jacksen.demo.view.canvas;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ComposeShader;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import com.jacksen.demo.view.R;

/**
 * @author jacksen
 *         <br/>
 * @since 2017/6/25
 */

public class MyCanvasView extends View {

    private Paint paint;

    private float[] points = new float[]{10, 10, 100, 10, 200, 100};

    private float[] lines = new float[]{0, 0, 100, 0, 0, 0, 100, 100, 0, 0, 0, 100};

    private Rect rect = new Rect(150, 150, 300, 500);
    private RectF rectF = new RectF(100.5f, 100.5f, 400.5f, 600.0f);

    private int radius = 0;

    private PorterDuffXfermode xfermode = new PorterDuffXfermode(PorterDuff.Mode.OVERLAY);

    private Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.child);

    private BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

    private BitmapShader bitmapShader2 = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);

    private BitmapShader bitmapShader3 = new BitmapShader(bitmap, Shader.TileMode.MIRROR, Shader.TileMode.REPEAT);

    public MyCanvasView(Context context) {
        this(context, null);
    }

    public MyCanvasView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyCanvasView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        setLayerType(LAYER_TYPE_SOFTWARE, null);
        paint = new Paint();
//        paint.setColor(Color.RED);
//        paint.setStrokeWidth(5);
        paint.setAntiAlias(true);
//        paint.setShadowLayer(10, 3, 3, Color.YELLOW);
//        paint.setStyle(Paint.Style.FILL);


    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int size = Math.min(getMeasuredWidth(), getMeasuredHeight());
        radius = size / 2;

        setMeasuredDimension(size, size);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Log.d("MyCanvasView", "onDraw" + xfermode.toString());

//        canvas.drawPaint(paint);


//        canvas.drawLine(100, 100, 200, 200, paint);

//        canvas.drawLines(lines, paint);

//        canvas.drawLines(lines, 2, 8, paint);


//        paint.setStrokeWidth(50);
//        paint.setColor(Color.BLACK);
//        canvas.drawPoint(200, 200, paint);


//        canvas.drawPoints(points, paint);

//        canvas.drawPoints(points, 1, 4, paint);

       /* paint.setColor(Color.GRAY);
        paint.setStrokeWidth(10);*/

//        canvas.drawArc(rectF, 0, 90, true, paint);
//
//        paint.setColor(Color.RED);
//        canvas.drawArc(rectF, 90, 90, false, paint);
//
//        paint.setColor(Color.BLUE);
//        canvas.drawArc(rectF, 180, 90, true, paint);
//
//        paint.setColor(Color.BLACK);
//        canvas.drawArc(rectF, 270, 90, false, paint);

//        canvas.drawArc(0, 0, 300, 300, 30, 90, true, paint);
//        paint.setColor(Color.GRAY);
//        canvas.drawArc(0, 0, 300, 300, 30, -90, true, paint);

//        paint.setStyle(Paint.Style.STROKE);

//        canvas.drawCircle(200, 200, 100, paint);


        /*canvas.drawOval(rectF, paint);

        paint.setColor(Color.RED);
        paint.setStyle(Paint.Style.STROKE);
        canvas.drawOval(150, 300, 700, 700, paint);*/


        /*canvas.drawRect(rect, paint);
        paint.setColor(Color.RED);
        paint.setStyle(Paint.Style.STROKE);
        canvas.drawRect(rectF, paint);
        paint.setColor(Color.YELLOW);
        canvas.drawRect(50.0f, 50.0f, 650.0f, 650.0f, paint);*/

        /*canvas.drawRoundRect(rectF, 30, 30, paint);

        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(Color.YELLOW);
        canvas.drawRoundRect(50.0f, 50.0f, 600.f, 300.f, 30, 30, paint);*/


        // xfermode


        /*radius = canvas.getWidth() / 3;
        canvas.drawColor(Color.BLACK);

        int sc = canvas.saveLayer(0, 0, canvas.getWidth(), radius * 3, null, Canvas.ALL_SAVE_FLAG);

        // 1. bg
//        canvas.drawColor(Color.parseColor("#E0EEE0"));
        canvas.drawARGB(0, 0, 0, 0);

        // 2. dst

        paint.setColor(0xFFFFCC44);
        canvas.drawCircle(radius, radius, radius, paint);
//        canvas.drawBitmap(makeDst(radius * 2, radius * 2), 0, 0, paint);


        // 3. src
        paint.setXfermode(xfermode);
        paint.setColor(0xFF66AAFF);
        canvas.drawRect(radius, radius, radius * 2.5f, radius * 2.5f, paint);
//        canvas.drawBitmap(makeSrc((int) (radius * 1.5f), (int) (radius * 1.5f)), radius, radius, paint);


        paint.setXfermode(null);
        canvas.restoreToCount(sc);*/


        // save & restore


        /*canvas.save();
        canvas.rotate(90, canvas.getWidth() / 2, canvas.getHeight() / 2);

        paint.setStrokeWidth(20);
        paint.setColor(Color.RED);
        canvas.drawLine(canvas.getWidth() / 2, 0, canvas.getWidth() / 2, canvas.getHeight(), paint);

        canvas.restore();
        canvas.drawCircle(canvas.getWidth() - 100, canvas.getWidth() - 100, 100, paint);*/


        /*radius = canvas.getWidth() / 3;
        paint.setColor(0xFFFFCC44);
        Bitmap bitmap = makeDst(radius, radius);
        Rect dstRect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        Rect srcRect = new Rect(0, 0, bitmap.getWidth() / 2, bitmap.getHeight() / 2);
        canvas.drawBitmap(bitmap, srcRect, dstRect, paint);

        paint.setColor(0xFF66AAFF);
        paint.setStyle(Paint.Style.STROKE);
        canvas.drawRect(0, 0, bitmap.getWidth(), bitmap.getHeight(), paint);*/

        /*paint.setShader(bitmapShader2);
        int radius = bitmap.getWidth() / 2;
        if (bitmap.getHeight() < bitmap.getWidth()) {
            radius = bitmap.getHeight() / 2;
        }
        canvas.drawCircle(bitmap.getWidth(), bitmap.getHeight(), radius * 2, paint);*/


        int w = getWidth();
        int h = getHeight();

        /*float mScale = (radius * 2.0f) / Math.min(bitmap.getHeight(), bitmap.getWidth());

        Matrix matrix = new Matrix();
        matrix.setScale(mScale, mScale);

        bitmapShader2 = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); // 模式无所谓了
        bitmapShader2.setLocalMatrix(matrix);
        paint.setShader(bitmapShader2);*/
//        canvas.drawCircle(radius, radius, radius, paint);

        /*paint.setTextSize(300.0f);
        paint.setColor(Color.BLACK);
        paint.setTextSkewX(-0.5f); // X轴错切
        canvas.drawText("笨小孩", 0, radius, paint);*/

//        canvas.drawPath(getPentagonPath(), paint);


        /*LinearGradient linearGradient = new LinearGradient(0, 0, w, 0,
                new int[]{Color.RED,
                        Color.BLUE,
                        Color.BLACK,
                        Color.YELLOW}, null, Shader.TileMode.CLAMP);
        paint.setShader(linearGradient);
//        canvas.drawRect(0, 0, w, h, paint);
        paint.setTextSize(70.0f);
        canvas.drawText("世间安得双全法,不负如来不负卿", 0, radius, paint);*/


        /*RadialGradient radialGradient = new RadialGradient(radius, radius, radius, new int[]{Color.YELLOW, Color.RED, Color.BLUE, Color.MAGENTA}, new float[]{0.2f, 0.2f, 0.5f, 1f}, Shader.TileMode.REPEAT);
        paint.setShader(radialGradient);
        canvas.drawCircle(radius, radius, radius, paint);*/

        /*SweepGradient sweepGradient = new SweepGradient(radius, radius, new int[]{Color.YELLOW, Color.BLUE, Color.GREEN, Color.BLACK}, null);
        paint.setShader(sweepGradient);
        canvas.drawCircle(radius, radius, radius, paint);*/


        BitmapShader bitmapShader = new BitmapShader(getCircleBitmap(radius / 4), Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
        LinearGradient linearGradient = new LinearGradient(0, 0, w, h,
                new int[]{Color.RED,
                        Color.BLUE,
                        Color.BLACK,
                        Color.YELLOW}, null, Shader.TileMode.CLAMP);

        ComposeShader composeShader = new ComposeShader(bitmapShader, linearGradient, PorterDuff.Mode.SRC_IN);
        paint.setShader(composeShader);
        canvas.drawRect(0, 0, w, h, paint);
    }

    public Path getPentagonPath() {
        Path path = new Path();

        float radian = degree2Radian(36);// 36为五角星的角度
        float radius_in = (float) (radius * Math.sin(radian / 2) / Math
                .cos(radian)); // 中间五边形的半径

        path.moveTo((float) (radius * Math.cos(radian / 2)), 0);// 此点为多边形的起点
        path.lineTo((float) (radius * Math.cos(radian / 2) + radius_in
                        * Math.sin(radian)),
                (float) (radius - radius * Math.sin(radian / 2)));
        path.lineTo((float) (radius * Math.cos(radian / 2) * 2),
                (float) (radius - radius * Math.sin(radian / 2)));
        path.lineTo((float) (radius * Math.cos(radian / 2) + radius_in
                        * Math.cos(radian / 2)),
                (float) (radius + radius_in * Math.sin(radian / 2)));
        path.lineTo(
                (float) (radius * Math.cos(radian / 2) + radius
                        * Math.sin(radian)), (float) (radius + radius
                        * Math.cos(radian)));
        path.lineTo((float) (radius * Math.cos(radian / 2)),
                (float) (radius + radius_in));
        path.lineTo(
                (float) (radius * Math.cos(radian / 2) - radius
                        * Math.sin(radian)), (float) (radius + radius
                        * Math.cos(radian)));
        path.lineTo((float) (radius * Math.cos(radian / 2) - radius_in
                        * Math.cos(radian / 2)),
                (float) (radius + radius_in * Math.sin(radian / 2)));
        path.lineTo(0, (float) (radius - radius * Math.sin(radian / 2)));
        path.lineTo((float) (radius * Math.cos(radian / 2) - radius_in
                        * Math.sin(radian)),
                (float) (radius - radius * Math.sin(radian / 2)));

        path.close();// 使这些点构成封闭的多边形

        return path;

    }

    private float degree2Radian(int degree) {
        return (float) (Math.PI * degree / 180);
    }


    static Bitmap getCircleBitmap(int radius) {
        Bitmap bm = Bitmap.createBitmap(radius * 2, radius * 2, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bm);
        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);

        p.setColor(Color.WHITE);
        c.drawCircle(radius, radius, radius, p);
        return bm;
    }

    // dst
    static Bitmap makeDst(int w, int h) {
        Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bm);
        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);

        p.setColor(0xFFFFCC44);
        c.drawOval(new RectF(0, 0, w, h), p);
        return bm;
    }

    // src
    static Bitmap makeSrc(int w, int h) {
        Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bm);
        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);

        p.setColor(0xFF66AAFF);
        c.drawRect(0, 0, w, h, p);
        return bm;
    }

    /**
     * @param mode
     */
    public void changeXfermode(PorterDuff.Mode mode) {
        xfermode = new PorterDuffXfermode(mode);
        invalidate();
    }
}
